#include <surface\pointsBin.h>
#include <io\pngstream.h>
#include <base\global.h>
#include <geo\inverseMercatorProjection.h>

#include <sstream>
#include <iostream>

pointsBin::pointsBin(vec2i tile_id_, vec2i size_) {
  tile_id = tile_id_;
  size = size_;

  filled = 0;

  heights = new s_point_set *[size[1]];

  for (int row = 0; row != size[1]; row++) {
    heights[row] = new s_point_set[size[0]];
  }
}

pointsBin::~pointsBin() {

  for (int row = 0; row != size[1]; row++) {
    delete [] heights[row];
  }

  delete [] heights;
}

void
pointsBin::save(string filename, float multiplier) {
  pngstream pngs;

  FILE *fout;
  fopen_s(&fout, filename.c_str(), "wb");
  pngs.initializeOutput(fout, 32, 32, 16, PNG_COLOR_TYPE_GRAY);

  unsigned short **data = new unsigned short *[32];

  for (int row = 0; row != 32; row++) {
    data[row] = new unsigned short [32];
  }

  for (int row = 0; row != 32; row++) {
    for (int col = 0; col != 32; col++) {
      data[row][col] = (short) (ROUND(heights[row][col].height * multiplier));
      //std::cout << (short) (ROUND(heights[row][col].height * 10.0)) << " ";
    }
    //std::cout << std::endl;
  }

  pngs.write((unsigned char **) data);
  pngs.finishOutput();
  fclose(fout);

  for (int row = 0; row != 32; row++) {
    delete [] data[row];
  }
  std::cout << std::endl;

  delete [] data;

/*
  fopen_s(&fout, filename.c_str(), "rb");
  pngs.initializeInput(fout, false);

  int row = 0;
  while(pngs.hasNext()) {
    data[row] = (unsigned short *) pngs.readLine();
    for (int c = 0; c != 32; c++) {
     std::cout << data[row][c] << " ";
    }
    std::cout << std::endl;
    row++;
  }
  pngs.finishInput();
  fclose(fout);

  stringstream bytes_stream(ios::in | ios::out || ios::binary);
  bytes_stream << data[0];

  bytes_stream.seekg(0, ios::beg);
  short height;
  bytes_stream >> height;
  height = data[0][0];
  //height |= data[0][1];
  std::cout << height;
*/
}

bool 
pointsBin::addHeight(int global_x, int global_y, double height) {
  int x = global_x % size[0];
  int y = global_y % size[1];

  if (!heights[y][x].set) {

    heights[y][x].height = height;
    heights[y][x].x = global_x;
    heights[y][x].y = global_y;
    heights[y][x].set = true;
    filled++;

    return (filled == size[0] * size[1]);
  }
  else {
    std::cerr << "value already set" << endl;
    exit(1);
  }
  return false;
}